// (C) 2022 Intel Corporation. All rights reserved.
// Your use of Intel Corporation's design tools, logic functions and other 
// software and tools, and its AMPP partner logic functions, and any output 
// files from any of the foregoing (including device programming or simulation 
// files), and any associated documentation or information are expressly subject 
// to the terms and conditions of the Intel Program License Subscription 
// Agreement, Intel FPGA IP License Agreement, or other applicable 
// license agreement, including, without limitation, that your use is for the 
// sole purpose of programming logic devices manufactured by Intel and sold by 
// Intel or its authorized distributors.  Please refer to the applicable 
// agreement for further details.

`define SIGNATURE_ADDR                         16'h00
`define VERSION_CAPBILITY_ADDR                 16'h04
`define REMOTE_JUMPER_CONTROL_ADDR             16'h08

module RJO_CSR
    #(
        parameter JUMPER_COUNT  = 6'd48,
		  parameter  SIGNATURE    = 32'h2443_4A52
   
    )
(
    input                          Clock,                        //FPGA Primary Synchronous Clock
    input                          Reset,                        //Synchronous Reset
    input                          FM_VAL_DBG_JUMPER_EN,         //physical jumper indicate RJC enabled
    input                          iT_Reset,                     //come from PFR CSR
    input                          iPLTRST_N,
    input                          iSlpS3,
	 input                     	  iAUX_PWRGD_CPU,    

    input                          iCPU0_MEM_Done,    //come from CPU SGPIO, indicate CPU0 Main power rail is ok
    input                          iCPU1_MEM_Done,    //come from CPU SGPIO, indicate CPU1 Main power rail is ok
    output [JUMPER_COUNT+12-1:0]   CurrentValue , 
    input  [JUMPER_COUNT+12-1:0]   JumperIn,  
    output                         invalid_access,
	
   input			  [ 7:0] bidin,					//Bifurcation ID
   output  		 reg	  [7:0]      bidout,				//Bifurcation ID
	 output                          FM_TTK_SPI_EN_RJC_N_Override        ,
	 output                          PFR_DEBUG_JUMPER_RJC_N_Override     ,
	 output                          PFR_FORCE_RECOVERY_RJC_N_Override   ,
	 output                          FM_TTK_SPI_EN_RJC_N_Value           ,
	 output                          PFR_DEBUG_JUMPER_RJC_N_Value        ,
	 output                          PFR_FORCE_RECOVERY_RJC_N_Value      ,	 
	 
    //avmm interface connect to I2C ,BMC interface use 32 bit avmm
    input                   [31:0] avmm_address,    
    input                          avmm_write,      
    input                   [31:0] avmm_writedata,          
    input                          avmm_read,     
    output              reg [31:0] avmm_readdata,      
    output              reg        avmm_readdatavalid, 
    output                         avmm_waitrequest,           
    input                   [ 3:0] avmm_byteenable,


    output    [JUMPER_COUNT+12-1:0]    oOvDis, 

    //side band signals connect to flash
    input         [31: 0] UFMLdData,         //Data read out from flash
    output  reg   [31: 0] FlashOpAddr,       //Address for flash write and read operation
    output  reg   [ 5: 0] FlashOpLen,        //Number of 32-bit words to do in write operation
    output  reg   [31: 0] FlashRJCWrData,
    

    output    reg      FlashWriteEn,         //Starts a flash write if unlocked and ready
    output    reg      FlashEraseEn,         //Starts a flash erase if unlocked and ready
    output    reg      FlashReadEn,          //Starts a flash read if unlocked and ready

    input              FlashWrBusy,          //Flash write operation is currently under way
    input              FlashRdBusy,          //Flash Read operation is currently under way
    input              FlashEraseBusy,       //Acknowledges flash command to clear lock and command bits
    
    input              FlashWrSuccess,         //Flash write operation is currently under way
    input              FlashRdSuccess,         //Flash Read operation is currently under way
    input              FlashEraseSuccess,      //Acknowledges flash command to clear lock and command bits
    input              loaddataen,
    input              FlashError,             //An error has occurred with the flash command， reserved for debug                   

    input              RSU_FlashBusy,
    input      [5: 0]  UFMOpWriteCnt,
	 input      [5: 0]  ReadCnt

    );
//The current time value comes from master_fub module in CPU FPGA, if the system power up and no power down behavior, then now it is Runtime

    localparam Runtime                  = 3'd0;
    localparam WARM_RESET               = 3'd1;
    localparam COLD_RESET               = 3'd2;
    localparam GLOBAL_RESET             = 3'd3;
    localparam T_RESET                  = 3'd4;
 

    localparam  T_1mS_2M                = 4'd2;
	 
reg        rPLTRST_N_FF         ;
reg 		  rSlpS3_FF            ;
reg 		  rAUX_PWRGD_CPU_FF    ;
reg 		  rT_Reset_FF          ;
		  
reg 		  rPLTRST_N_NEG        ;
reg 		  rSlpS3_NEG           ;
reg 		  rAUX_PWRGD_CPU_NEG   ;
reg 		  rT_Reset_NEG         ;

reg          [JUMPER_COUNT+12-1:0]  CurrentValue_En;
reg                                 invalid_read ;
reg                                 invalid_write;
reg                                r1msTimerStart;
reg                                w1msTimerDone ;
reg                        [ 2:0]  CurrentTime   ;
wire                       [15:0]  addr_local    ;                            //Only 16 bits out of 32 bits avmm_address supported
//Control CSR
reg                            FlashWrTrigger   ;


reg   [JUMPER_COUNT+12-1:0]        ValidJump        ;              

reg   [JUMPER_COUNT+12+2:0][31:0]  RegFile          ;        //Registers - 16 bit x MAX_ADDR
reg                             write_pose       ;
//Jumper CSR reg
reg   [JUMPER_COUNT+12-1:0][2:0]  Updatetime        ;        //RW
reg   [JUMPER_COUNT+12-1:0]       OvDis             ;        //Override disable,RW
reg   [JUMPER_COUNT+12-1:0]       OvVal             ;        //Override value,RW
wire  [JUMPER_COUNT+12-1:0]       wOverride         ;
wire  [JUMPER_COUNT+12-1:0]       wTimeMatch        ;
reg                            UFMTrigger        ;
	
reg        rdefault_restore     ;                            //jumper default value restore
reg        Flashreadctrl        ;			     //flash load control
reg   [JUMPER_COUNT+12-1:0]     CurrentValue_reg    ;	     
	
	
assign avmm_waitrequest    = 1'b0; //Fix wait request to 1'b0 as no wait needed

//Use simple names for clarity in module - this module only uses the lower 16 bits
assign addr_local          = {2'b0,avmm_address[15:2]};


//Use write_pose to indicate whether BMC starts write CSR after AC Cycle, Load CSR from UFM should happen before that 
 
always @ ( posedge Clock ) begin
    if ( Reset ) begin
        write_pose         <= 1'b0;
    end else begin
        if ( avmm_write  ) begin
            write_pose     <= 1'b1; 
        end
        else begin
            write_pose     <= write_pose;
        end
    end
end
////////////////////////////////////////////////
//BMC read CSR
///////////////////////////////////////////////
always @ ( posedge Clock ) begin
    if ( Reset ) begin
        avmm_readdatavalid     <= 1'b0;
    end else begin
        if ( avmm_read && (&avmm_byteenable)) begin
            avmm_readdatavalid <= 1'b1; //readvalid asserts one clock cycle after read assetted.
        end else begin
            avmm_readdatavalid <= 1'b0;
        end
    end
end

always @ ( posedge Clock ) begin
    if (Reset) begin 
        avmm_readdata          <= 32'h0;
    end else if (avmm_read ) begin
         if(addr_local < JUMPER_COUNT +12 + 3)
			
			avmm_readdata         <= RegFile[addr_local];
			else 
			
			avmm_readdata         <= 32'h0;      //  return bad address 
    end else begin 
         avmm_readdata         <= 32'h0;      //  return bad address 
    end 

end

////////////////////////////////////////////////
//CSR Definition
///////////////////////////////////////////////

 //Register for signature and version control 
  

  always @(posedge Clock)
  begin
    if(Reset) begin
      RegFile[`SIGNATURE_ADDR/4]                  <= 32'h0;
      RegFile[`VERSION_CAPBILITY_ADDR/4]          <= 32'h0;
	    RegFile[`REMOTE_JUMPER_CONTROL_ADDR/4]      <= 32'h0000_C800;
    end 
     else begin  
      RegFile[`SIGNATURE_ADDR/4]                        <= SIGNATURE;
      RegFile[`VERSION_CAPBILITY_ADDR/4]                <= {FM_VAL_DBG_JUMPER_EN,31'h4000_0000};
	     RegFile[`REMOTE_JUMPER_CONTROL_ADDR/4]            <=      {18'h0,CurrentTime,FlashEraseSuccess,FlashEraseBusy,FlashEraseEn,FlashRdSuccess,FlashRdBusy,FlashReadEn,FlashWrSuccess,FlashWrBusy,FlashWriteEn,rdefault_restore,UFMTrigger};
  end
end 

 //Register for RJC Control REG

  always @(posedge Clock)
  begin
	if(Reset) begin
  
     FlashWrTrigger              <= 1'b0;
     rdefault_restore            <= 1'b0;
    end	  

    else begin 
       if ( FlashRdSuccess && avmm_write && !( |avmm_address[31:16]) && (&avmm_byteenable) && !(|avmm_writedata[31:2])) begin   //BMC users should wait for Load CSR success then trigger write  
          case (avmm_address)
           `REMOTE_JUMPER_CONTROL_ADDR: begin
		   FlashWrTrigger       <= avmm_writedata[0];
		   rdefault_restore     <= avmm_writedata[1];
           end

		  endcase
       end
    else begin 
        FlashWrTrigger              <= 1'b0;
	rdefault_restore            <= rdefault_restore;
    end

  end
end 


//invalid_write, using combinational logic to report error
always @ ( * ) begin
    if ( Reset ) begin
		  invalid_write                 = 1'b0;
    end else begin
        if ( avmm_write && (&avmm_byteenable)) begin
		if((avmm_address == `REMOTE_JUMPER_CONTROL_ADDR)&&!(|avmm_writedata[31:2]))
			        	  
                    invalid_write                 = 1'b0;
				  else  if ((addr_local<JUMPER_COUNT+12+3 )&&!(|avmm_writedata[31:6])&&(!avmm_writedata[0]))
				  invalid_write                 = 1'b0;
			     else  	  invalid_write        =1'b1;
        end
	     else begin
	        invalid_write              =   1'b0;
        end
    end
end


//invalid_read, using combinational logic to report error
always @ ( * ) begin
    if ( Reset ) begin
        invalid_read       = 1'b0;
    end else begin
        if ( avmm_read  && (&avmm_byteenable)) begin
            if(|avmm_address[31:16]) invalid_read       = 1'b1;
				else if ((addr_local < JUMPER_COUNT +12 + 3 ) && !(|avmm_address[1:0])) invalid_read       = 1'b0;
				else invalid_read       = 1'b1;
        end
		  else begin
		     invalid_read                    =   1'b0;
        end
    end
end

assign invalid_access   =  invalid_write || invalid_read;

/////////////////////////////////////////
// Flash operation
//State machine to control flash 
/////////////////////////////////////////
parameter [3:0]
    ST_INIT                  =  0,
    ST_DISABLE_RJC           =  1,
    ST_LOAD_UFM              =  2,
    ST_WAIT_TRIGGER          =  3,
    ST_ERASE_UFM             =  4,
    ST_WRITE_UFM             =  5,
    ST_LOAD_UFM_2            =  6,
    ST_LOAD_UFM_c1           =  7, 
    ST_LOAD_UFM_c2           =  8,
    ST_LOAD_UFM_c3           =  9,
    ST_LOAD_UFM_c4           = 10,
    ST_LOAD_UFM_2_c1           = 11, 
    ST_LOAD_UFM_2_c2           = 12,
    ST_LOAD_UFM_2_c3           = 13,
    ST_LOAD_UFM_2_c4           = 14;
reg [3:0] CurrentState, NextState;
  //Register  for UFMTrigger 

  always @(posedge Clock)
  begin
    if(Reset)
      UFMTrigger <= 1'b0;
    else if(CurrentState == ST_WRITE_UFM)
      UFMTrigger <= 1'b0;
    else if(FlashWrTrigger)
      UFMTrigger <= 1'b1;
    else
      UFMTrigger <= UFMTrigger;
  end
  
//RJC - Remote default restore control
always @(posedge Clock)
begin
	if (Reset) begin
	Flashreadctrl <= 1'b1;
	end
	else if (!FM_VAL_DBG_JUMPER_EN || rdefault_restore) begin
		if(CurrentState == ST_LOAD_UFM_2) begin
			Flashreadctrl <= 1'b0;
		end
		else begin
			Flashreadctrl <= Flashreadctrl;
		end
	end
	else begin
	Flashreadctrl <= 1'b1;
	end
end


 always @(posedge Clock)
  begin
    if(Reset)
      CurrentState <= ST_INIT;
    else
      CurrentState <= NextState;
  end
   always @(CurrentState or FM_VAL_DBG_JUMPER_EN or FlashEraseSuccess or FlashRdSuccess or UFMTrigger or FlashWrSuccess or RSU_FlashBusy or rdefault_restore)
  begin
    case(CurrentState)
    ST_INIT: begin
         NextState = ST_LOAD_UFM;
    end

    ST_DISABLE_RJC: begin
         if (FM_VAL_DBG_JUMPER_EN &&(!rdefault_restore) && !RSU_FlashBusy)
         NextState = ST_WAIT_TRIGGER;
         else if (!FlashEraseSuccess && !RSU_FlashBusy)
         NextState = ST_ERASE_UFM;
         else if (FlashEraseSuccess && Flashreadctrl && !RSU_FlashBusy)
	 NextState = ST_LOAD_UFM_2;
	 else NextState = ST_DISABLE_RJC;
    end

    ST_LOAD_UFM: begin
        if ((!FM_VAL_DBG_JUMPER_EN || rdefault_restore) && FlashRdSuccess)
        NextState = ST_DISABLE_RJC;  

         else NextState = ST_LOAD_UFM_c1;
    end
	 
    ST_LOAD_UFM_c1: begin
        NextState = ST_LOAD_UFM_c2;
    end
	 
    ST_LOAD_UFM_c2: begin
        NextState = ST_LOAD_UFM_c3;
    end

    ST_LOAD_UFM_c3: begin
        NextState = ST_LOAD_UFM_c4;
    end
	 
    ST_LOAD_UFM_c4: begin
    if(FlashRdSuccess && FM_VAL_DBG_JUMPER_EN && (!rdefault_restore))
	 NextState = ST_WAIT_TRIGGER;
    else if ((!FM_VAL_DBG_JUMPER_EN || rdefault_restore) && FlashRdSuccess)
	 NextState = ST_DISABLE_RJC;
    else NextState = ST_LOAD_UFM_c4;
    end
	    
    ST_LOAD_UFM_2: begin
        NextState = ST_LOAD_UFM_2_c1;
    end
    ST_LOAD_UFM_2_c1: begin
        NextState = ST_LOAD_UFM_2_c2;
    end
	 
    ST_LOAD_UFM_2_c2: begin
        NextState = ST_LOAD_UFM_2_c3;
    end

    ST_LOAD_UFM_2_c3: begin
        NextState = ST_LOAD_UFM_2_c4;
    end
	 
    ST_LOAD_UFM_2_c4: begin
        if(FlashRdSuccess)
        NextState = ST_DISABLE_RJC;
        else NextState = ST_LOAD_UFM_2_c4;
    end
		 
    ST_WAIT_TRIGGER:begin
       if (!FM_VAL_DBG_JUMPER_EN|| rdefault_restore)
        NextState = ST_DISABLE_RJC;  

       else if (UFMTrigger &&!RSU_FlashBusy)
        NextState = ST_ERASE_UFM;

       else NextState = ST_WAIT_TRIGGER;

    end
     
     ST_ERASE_UFM: begin
         if(FlashEraseSuccess && (!FM_VAL_DBG_JUMPER_EN || rdefault_restore))
             NextState = ST_DISABLE_RJC;
         else if  (FlashEraseSuccess && FM_VAL_DBG_JUMPER_EN &&(!rdefault_restore) && !RSU_FlashBusy)
             NextState = ST_WRITE_UFM;
         else  NextState = ST_ERASE_UFM;

     end

     ST_WRITE_UFM: begin
          if((!FM_VAL_DBG_JUMPER_EN || rdefault_restore) && FlashWrSuccess)
               NextState = ST_DISABLE_RJC; 
	     else if (FlashWrSuccess && FM_VAL_DBG_JUMPER_EN && (!rdefault_restore))
               NextState = ST_LOAD_UFM;
          else NextState = ST_WRITE_UFM;

     end

    endcase

  end 
 
  always @(CurrentState or FM_VAL_DBG_JUMPER_EN or FlashEraseSuccess or FlashRdSuccess or UFMTrigger or FlashWrSuccess or RSU_FlashBusy or rdefault_restore)
 begin 

         case(CurrentState)
          ST_INIT :
          begin 
            FlashReadEn                 =  1'b0;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b0;
          end
          ST_DISABLE_RJC:
          begin 
            FlashReadEn                 =  1'b0;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b0;
          end 
          ST_LOAD_UFM:
          begin
            FlashReadEn                 =  1'b1;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b0;
          end
		 
          ST_LOAD_UFM_c1:
          begin
            FlashReadEn                 =  1'b1;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b0;
          end
			 
	  ST_LOAD_UFM_c2:
          begin
            FlashReadEn                 =  1'b1;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b0;
          end
			 
          ST_LOAD_UFM_c3:
          begin
            FlashReadEn                 =  1'b1;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b0;
          end
			 
	  ST_LOAD_UFM_c4:
          begin
            FlashReadEn                 =  1'b1;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b0;
          end
	
	  ST_LOAD_UFM_2:
          begin
            FlashReadEn                 =  1'b1;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b0;
          end
			 
	  ST_LOAD_UFM_2_c1:
          begin
            FlashReadEn                 =  1'b1;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b0;
          end
			 
          ST_LOAD_UFM_2_c2:
          begin
            FlashReadEn                 =  1'b1;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b0;
          end
			 
	  ST_LOAD_UFM_2_c3:
          begin
            FlashReadEn                 =  1'b1;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b0;
          end
			 
	  ST_LOAD_UFM_2_c4:
          begin
            FlashReadEn                 =  1'b1;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b0;
          end	
		 
          ST_WAIT_TRIGGER: 
          begin 
            FlashReadEn                 =  1'b0;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b0;
          end 
          ST_ERASE_UFM:
          begin 
            FlashReadEn                 =  1'b0;
            FlashEraseEn                =  1'b1;
            FlashWriteEn                =  1'b0;
          end 
          ST_WRITE_UFM:
           begin 
            FlashReadEn                 =  1'b0;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b1;
           end 

           default:
           begin
            FlashReadEn                 =  1'b0;
            FlashEraseEn                =  1'b0;
            FlashWriteEn                =  1'b0; 
           end
         endcase
 end 


 always @(posedge Clock)
  begin
    if(Reset) begin
       FlashOpAddr  <= 32'b0;
       FlashOpLen   <= 6'b0;
    end 
    else begin
       FlashOpAddr  <= 32'b0;
       FlashOpLen   <= JUMPER_COUNT+12;

    end 

end 

  always @(posedge Clock)
  begin
    if(Reset) begin
        rPLTRST_N_FF         <= 1'b0;
		  rSlpS3_FF            <= 1'b0;
		  rAUX_PWRGD_CPU_FF    <= 1'b0;
		  rT_Reset_FF          <= 1'b0;
		  
		  rPLTRST_N_NEG        <= 1'b0;
		  rSlpS3_NEG           <= 1'b0;
		  rAUX_PWRGD_CPU_NEG   <= 1'b0;
		  rT_Reset_NEG         <= 1'b0;
		  
    end
    else begin
	     rPLTRST_N_FF         <= iPLTRST_N;
		  rSlpS3_FF            <= iSlpS3;
		  rAUX_PWRGD_CPU_FF    <= iAUX_PWRGD_CPU;
		  rT_Reset_FF          <= iT_Reset;
		  
		  rPLTRST_N_NEG        <=  rPLTRST_N_FF && !iPLTRST_N;  
		  rSlpS3_NEG           <=  rSlpS3_FF && !	iSlpS3;
		  rAUX_PWRGD_CPU_NEG   <=  rAUX_PWRGD_CPU_NEG && iAUX_PWRGD_CPU;
		  rT_Reset_NEG         <=  rT_Reset_FF && !iT_Reset;

	      end 

    end 

////////////////////////////////////////////////
////////Jumper CSR Register ////////////////////
////////////////////////////////////////////////


genvar i;
generate for(i=0;i<JUMPER_COUNT;i=i+1)

 begin: RJC 
  always @(posedge Clock)begin
   if ( Reset ) begin
          RegFile   [i+3]         <= 32'hFFFF_FFFF;


  end
  else if(loaddataen && !write_pose && (i == JUMPER_COUNT +12- ReadCnt))  begin     //If load UFM Value successful, and BMC didn't start to write
       
         RegFile   [i+3]          <=   {24'hFF_FFFF,UFMLdData[2:1], 3'b111,UFMLdData[2:1],JumperIn[i]};

       end
  
  else if(loaddataen && write_pose &&(i == JUMPER_COUNT +12- ReadCnt)) begin
			
			RegFile   [i+3][7:6]         <=  UFMLdData[2:1];
			RegFile   [i+3][31:8]        <=  RegFile   [i+3][31:8];
			RegFile   [i+3][5:0]         <=  RegFile   [i+3][5:0];
	
  end

//BMC start to write, so UFMLdData != RegFile Data unless AC Cycle
  else if ( FlashRdSuccess && avmm_write && !( |avmm_address[31:16]) && (&avmm_byteenable) ) begin
         if (i+3 == addr_local) begin
      			RegFile   [i+3][31:8]       <=  24'hFF_FFFF;
     			RegFile   [i+3][7:6]        <= 	RegFile [i+3][7:6];
     			RegFile   [i+3][5:0]        <=  {avmm_writedata[5:1],JumperIn[i]};  		 

         end
         else begin
			      RegFile[i+3][31:1]          <=   RegFile[i+3][31:1] ;
				  RegFile[i+3][0]           <=  JumperIn[i];

         end
     end 
  else begin

            RegFile[i+3][31:1]          <=   RegFile[i+3][31:1] ;
				 RegFile[i+3][0]           <=  JumperIn[i];

				
				
       end 
end 
  assign  Updatetime[i]           = RegFile[i+3][5:3];
  assign  OvDis[i]                = RegFile[i+3][2];
  assign  OvVal[i]                = RegFile[i+3][1];  
  
  end
endgenerate


	/////////////   Bifurcation ID Selection  //////////
/// RegFile of BID
genvar t;												
generate for(t=0;t<12;t=t+1)			// duplicate

 begin: BIF_ID_SEL 											// cycle name: Bifurcation ID Selection
  always @(posedge Clock)begin
   if ( Reset ) begin
         RegFile   [t+48+3]          <=	32'hFFFF_FFFF;				// reset, default value
  end
  else if(loaddataen && !write_pose && (t == 12 - ReadCnt))  begin     // If load UFM Value successful, and BMC didn't start to write   
         RegFile   [t+48+3]          <=   UFMLdData[31:0];			// data load from UFM, 32 bit
       end
  
  else if(loaddataen && write_pose && (t == 12 - ReadCnt)) begin			// write			
			RegFile   [t+48+3]          <=   UFMLdData[31:0];	
  end


//BMC start to write, so UFMLdData != RegFile Data unless AC Cycle
  else if ( FlashRdSuccess && avmm_write && !( |avmm_address[31:16]) && (&avmm_byteenable) ) begin			
         if (t+48+3 == addr_local) begin
              RegFile   [t+48+3]          <=   avmm_writedata[31:0]; 				// data write
         end
         else begin
			     RegFile	[t+48+3]          <=   RegFile	[t+48+3]; 					// keep original value
         end
     end 
  else begin
			     RegFile	[t+48+3]          <=   RegFile	[t+48+3]; 						
       end 
end 
  assign  Updatetime[t+48]           = RegFile[t+48+3][5:3];
  assign  OvDis[t+48]                = RegFile[t+48+3][2];
  assign  OvVal[t+48]                = RegFile[t+48+3][1];  
  
  end
endgenerate
/// endgenerate RegFile for BIF_ID_SEL
	
//////////////////////////////////////
////FlashCtrl Interface///////////////
//////////////////////////////////////


 always @(posedge Clock)
  begin
    if(Reset) begin
       FlashRJCWrData  <= 32'b0;
    end 
    else if (FlashWriteEn)begin 
	 
	 for(integer m = 0; m<JUMPER_COUNT+12;m=m+1) begin
	 
	   if ( m == JUMPER_COUNT +12- UFMOpWriteCnt ) begin 
         FlashRJCWrData  <= RegFile[m+3];
      end 

	 end
end 

    else FlashRJCWrData <= FlashRJCWrData;
end

  ///////////////////////////////////////
////////Jumper out control/////////////
///////////////////////////////////////
always @ ( posedge Clock ) begin
    if ( Reset ) begin
        CurrentTime         <= 3'b111;
    end else if (iT_Reset) CurrentTime <= T_RESET;
	     else if (rAUX_PWRGD_CPU_NEG) CurrentTime <= GLOBAL_RESET;
		  else if (rSlpS3_NEG) CurrentTime <= COLD_RESET;
		  else if (rPLTRST_N_NEG) CurrentTime <= WARM_RESET;
		  else CurrentTime <= Runtime;
		 
end  

genvar k;      
generate for(k=1;k<JUMPER_COUNT;k=k+1)
  begin: JumperControl
    always @(posedge Clock) begin
   if ( Reset )begin
	  CurrentValue_En[k] <= 1'b0;

	end
   else if(wOverride[k])
	   begin 
		   if(wTimeMatch[k])
				CurrentValue_En[k] <= OvVal[k];
	
		end
		
	else begin
	   CurrentValue_En[k] <= CurrentValue_En[k];

	end 

  
   end 
 
   assign CurrentValue[k]   =  wOverride[k]? CurrentValue_En[k]: 1'bz;

   assign wTimeMatch[k]     = ((Updatetime[k] == CurrentTime)||(Updatetime[k] == 3'b111)||(Updatetime[k] == 3'b000));
   assign wOverride[k]      = FlashRdSuccess && ValidJump[k]&&FM_VAL_DBG_JUMPER_EN&&(!rdefault_restore)&&!OvDis[k];
    
  end 
  endgenerate

/////////CMOS Clear need to generate 1ms pulse, when the override value turns to 1'b1, start to count
always @(posedge Clock) begin
   if ( Reset )begin
	  r1msTimerStart <= 1'b0;
	end

	else if ((( Updatetime[0] == CurrentTime)|| (Updatetime[0] == 3'b111)||(Updatetime[0] == 3'b000))&&FlashRdSuccess && ValidJump[0]&&FM_VAL_DBG_JUMPER_EN&&(!rdefault_restore)&&!OvDis[0]&& OvVal[0])
	  r1msTimerStart <= 1'b1;
	  	else if (CurrentValue[0] == 0) begin
	  r1msTimerStart <= 1'b0;
	end

	  
	 else  r1msTimerStart <= r1msTimerStart;
end
   delay #(.COUNT(T_1mS_2M)) 
     Timer1ms(
               .iClk(Clock),
               .iRst(Reset),
               .iStart(r1msTimerStart),
               .iClrCnt(1'b0),
               .oDone(w1msTimerDone)
               );
assign CurrentValue[0] = ( (( Updatetime[0] == CurrentTime)|| (Updatetime[0] == 3'b111))&&FlashRdSuccess && ValidJump[0]&&FM_VAL_DBG_JUMPER_EN&&(!rdefault_restore)&&!OvDis[0])? (OvVal[0]&& r1msTimerStart && !w1msTimerDone?1'b1:1'b0): 1'bz ;


//Use Jumeper Valid signal to avoid current leakage for jumpers at main rail
genvar j;
generate for(j=0;j<25;j=j+1)

 begin: JumperValid                 //Jumpers in AUX rail can be updated directly

 assign ValidJump[j] = 1'b1;

 end
 endgenerate

    assign       ValidJump[25]       =     1'b1;
    assign       ValidJump[26]       =     1'b1;
    assign       ValidJump[27]       =     1'b1;
    assign       ValidJump[28]       =     1'b1;
    assign       ValidJump[29]       =     1'b1;
    assign       ValidJump[30]       =     1'b1;
    assign       ValidJump[31]       =     1'b1;
    assign       ValidJump[32]       =     1'b1;
    assign       ValidJump[33]       =     1'b1;
    assign       ValidJump[34]       =     1'b1;
    assign       ValidJump[35]       =     1'b1;
    assign       ValidJump[36]       =     1'b1;
    assign       ValidJump[37]       =     1'b1;
    assign       ValidJump[38]       =     1'b1;
    assign       ValidJump[39]       =     1'b1;
    assign       ValidJump[40]       =     1'b1;
    assign       ValidJump[41]       =     1'b1;
    assign       ValidJump[42]       =     1'b1;
    assign       ValidJump[43]       =     1'b1;
    assign       ValidJump[44]       =     1'b1;
    assign       ValidJump[45]       =     1'b1;
    assign       ValidJump[46]       =     1'b1;
    assign       ValidJump[47]       =     1'b1;
	    
	 assign FM_TTK_SPI_EN_RJC_N_Override       =  wOverride[15]   ;
	 assign PFR_DEBUG_JUMPER_RJC_N_Override    =  wOverride[8]    ;
	 assign PFR_FORCE_RECOVERY_RJC_N_Override  =  wOverride[9]    ;
	 assign FM_TTK_SPI_EN_RJC_N_Value          = CurrentValue_En[15]        ;
	 assign PFR_DEBUG_JUMPER_RJC_N_Value       = CurrentValue_En[8]         ;
	 assign PFR_FORCE_RECOVERY_RJC_N_Value     = CurrentValue_En[9]         ;

   assign  oOvDis = OvDis ;// signal for mux input

	//////  RJC_CSR_BID_MUX   ///// 
always @(posedge Clock) begin
	case(bidin[7:0])
		// 0000xxxx, CPU0	
		8'b0000_0000: begin																																	
			bidout			<=		RegFile[0+48+3] [7: 0];  // #0	0xcc
		end
		8'b0000_0001: begin													
			bidout 			<= 		RegFile[0+48+3] [15:8];  // #1	
		end
		8'b0000_0010: begin
			bidout 			<= 		RegFile[0+48+3] [23:16]; // #2	
		end
		8'b0000_0011: begin
			bidout 			<= 		RegFile[0+48+3] [31:24]; // #3	
		end
    8'b0000_0100: begin																																	
			bidout			<=		RegFile[1+48+3] [7: 0]; // #4	  0xd0
		end
		8'b0000_0101: begin												
			bidout 			<= 		RegFile[1+48+3] [15:8]; // #5	
		end

 
		8'b0001_0000: begin                                         
			bidout 			<= 		RegFile[1+48+3] [23:16]; // #6	   
		end
		8'b0001_0001: begin
			bidout 			<= 		RegFile[1+48+3] [31:24]; // #7	
		end
    8'b0001_0010: begin																																	
			bidout			<=		RegFile[2+48+3] [7: 0];   // #8	0xd4
		end
		8'b0001_0011: begin														
			bidout 			<= 		RegFile[2+48+3] [15:8]; // #9	
		end
		8'b0001_0100: begin
			bidout 			<= 		RegFile[2+48+3] [23:16]; // #10	
		end
		8'b0001_0101: begin
			bidout 			<= 		RegFile[2+48+3] [31:24]; // #11	
		end

    


    8'b0010_0000: begin																																	
			bidout			<=		RegFile[3+48+3] [7: 0];   // #12	
		end
		8'b0010_0001: begin													
			bidout 			<= 		RegFile[3+48+3] [15:8]; // #13	
		end
		8'b0010_0010: begin
			bidout 			<= 		RegFile[3+48+3] [23:16]; // #14	
		end
		8'b0010_0011: begin
			bidout 			<= 		RegFile[3+48+3] [31:24]; // #15	
		end
    8'b0010_0100: begin																																		
			bidout			<=		RegFile[4+48+3] [7: 0];   // #16	
		end
		8'b0010_0101: begin													
			bidout 			<= 		RegFile[4+48+3] [15:8]; // #17	
		end



		8'b0011_0000: begin
			bidout 			<= 		RegFile[4+48+3] [23:16]; // #18	
		end
		8'b0011_0001: begin
			bidout 			<= 		RegFile[4+48+3] [31:24]; // #19	
    end

    8'b0011_0010: begin																																	
			bidout			<=		RegFile[5+48+3] [7: 0];   // #20	
		end
		8'b0011_0011: begin													
			bidout 			<= 		RegFile[5+48+3] [15:8];   // #21	
		end
		8'b0011_0100: begin
			bidout 			<= 		RegFile[5+48+3] [23:16]; // #22	
		end
		8'b0011_0101: begin
			bidout 			<= 		RegFile[5+48+3] [31:24]; // #23	
    end




    8'b0100_0000: begin																																		
			bidout			<=		RegFile[6+48+3] [7: 0];   // #24	
		end
		8'b0100_0001: begin													
			bidout 			<= 		RegFile[6+48+3] [15:8];   // #25	
		end
		8'b0100_0010: begin
			bidout 			<= 		RegFile[6+48+3] [23:16];  // #26	
		end
		8'b0100_0011: begin
			bidout 			<= 		RegFile[6+48+3] [31:24];  // #27	
    end

    8'b0100_0100: begin																																		
			bidout			<=		RegFile[7+48+3] [7: 0];   // #28	
		end
		8'b0100_0101: begin													
			bidout 			<= 		RegFile[7+48+3] [15:8];  // #29	
		end




		8'b0101_0000: begin
			bidout 			<= 		RegFile[7+48+3] [23:16]; // #30	
		end
		8'b0101_0001: begin
			bidout 			<= 		RegFile[7+48+3] [31:24]; // #31	
    end
    8'b0101_0010: begin																																			
			bidout			<=		RegFile[8+48+3] [7: 0];  // #32	
		end
		8'b0101_0011: begin													
			bidout 			<= 		RegFile[8+48+3] [15:8]; // #33	
		end
		8'b0101_0100: begin
			bidout 			<= 		RegFile[8+48+3] [23:16]; // #34	
		end
		8'b0101_0101: begin
			bidout 			<= 		RegFile[8+48+3] [31:24]; // #35	
    end



    8'b0110_0000: begin																																		
			bidout			<=		RegFile[9+48+3] [7: 0];  // #36	 
		end
		8'b0110_0001: begin													
			bidout 			<= 		RegFile[9+48+3] [15:8];  // #37	
		end
		8'b0110_0010: begin
			bidout 			<= 		RegFile[9+48+3] [23:16]; // #38	
		end
		8'b0110_0011:begin
			bidout 			<= 		RegFile[9+48+3] [31:24]; // #39	
    end
    8'b0110_0100: begin																																		
			bidout			<=		RegFile[10+48+3] [7: 0];  // #40	
		end
		8'b0110_0101: begin													
			bidout 			<= 		RegFile[10+48+3] [15:8]; // #41	
		end



		8'b0111_0000: begin
			bidout 			<= 		RegFile[10+48+3] [23:16]; // #42	
		end
		8'b0111_0001: begin
			bidout 			<= 		RegFile[10+48+3] [31:24]; // #43	
    end
    8'b0111_0010: begin																																			
			bidout			<=		RegFile[11+48+3] [7: 0];   // #44	
		end
		8'b0111_0011: begin													
			bidout 			<= 		RegFile[11+48+3] [15:8];  // #45	
		end
		8'b0111_0100: begin
			bidout 			<= 		RegFile[11+48+3] [23:16]; // #46	
		end
		8'b0111_0101: begin
			bidout 			<= 		RegFile[11+48+3] [31:24]; // #47	
    end



		default: begin
			bidout			<= 		16'hffff;						// default
		end
	endcase
end


endmodule


